package com.ruoyi.smartai.service.impl;

import com.ruoyi.common.constant.ReceivedMessage;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.smartai.entity.DialogueManagement;
import com.ruoyi.smartai.service.IDialogIntentService;
import com.ruoyi.smartai.service.IDialogueService;
import com.ruoyi.smartai.service.IDynamicQuartzService;
import com.ruoyi.smartai.utils.WhatsAPPUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.smartai.CurrentScenarioData;
import com.ruoyi.system.domain.smartai.ScenarioData;
import com.ruoyi.system.domain.smartai.ScenarioDataUtils;
import com.ruoyi.system.domain.smartai.SceneDetail;
import com.ruoyi.system.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
public class DialogueServiceImpl implements IDialogueService {
    private static final Logger log = LoggerFactory.getLogger(DialogueServiceImpl.class);

    @Autowired(required = false)
    private CustomerInfoMapper customerInfoMapper;

    @Autowired(required = false)
    private StandardScriptMapper standardScriptMapper;

    @Autowired(required = false)
    private FansInfoMapper fansInfoMapper;

    @Autowired(required = false)
    private ChatLogMapper chatLogMapper;

    @Autowired(required = false)
    private GeneralBaseMapper generalBaseMapper;

    @Autowired(required = false)
    RedisCache redisCache;

//    @Autowired(required = false)
//    private IDialogIntentService dialogIntentService;

    @Autowired(required = false)
    private IDynamicQuartzService dynamicQuartzService;

    private static final String SCENARIO_KEY_PREFIX = "persona:scenario:";
    public static final String SCENARIO_FANS_KEY_PREFIX = "persona:scenario:fans:";

    //最大回复
    private static final int MESSAGE_COUNT_THRESHOLD = 5;

    @Value("${apiSevicePath.similar_text}")
    private String similarTextUrl;

    @Value("${apiSevicePath.secketSendmessage}")
    private String newChatURL;

    @Value("${apiSevicePath.translateByTarget}")
    private String translateByTarget;

//    @Value("${apiSevicePath.secketSendmessage}")
//    private String newChatURL;

    @Override
    public int startForCustomerIds(String[] ids, String url) {
        try {
            List<CustomerInfo> list = customerInfoMapper.selectToids(ids);
            list.stream().forEach(customerInfo -> {
                // 在这里对每个 customerInfo 执行操作
                FansInfo fansInfo = fansInfoMapper.selectChatByCustomerNumber(customerInfo.getContactNumber());
                if (fansInfo != null) {
                    log.info(customerInfo.getContactNumber() + " 准备向 " + fansInfo.getClientNumber() + " 开始发送信息");
                    startDialog(url, fansInfo);
                    fansInfo.setStartTime(DateUtils.dateTime());
                    fansInfoMapper.updateDaysNumberByClientNumber(fansInfo);
                } else {
                    throw new ServiceException(String.format("客服【%s】粉丝为空，请添加粉丝", customerInfo.getContactNumber()));
                }
            });

            long randomDelay = 3000 + (long) (Math.random() * 5 * 1000);
            // 延时等待
            Thread.sleep(randomDelay);
        } catch (Exception e) {
            log.error("startForCustomerIds error" + e);
        }
        return 0;
    }

    @Override
    public int startForFansIds(String[] ids, String url) {
        try {
            List<FansInfo> list = fansInfoMapper.selectChatByIds(ids);
            list.stream().forEach(fansInfo -> {
                CustomerInfo customerInfo = customerInfoMapper.selectUserByNumber(fansInfo.getCustomerNumber());
                if (!customerInfo.getLinkStatus().equals("0")) {
                    log.error("startForFansIds 客服状态不在线");
                    throw new ServiceException("请先关联账户：" + customerInfo.getContactNumber());
                }
                startDialog(url, fansInfo);
                fansInfo.setStartTime(DateUtils.dateTime());
                fansInfoMapper.updateDaysNumberByClientNumber(fansInfo);
            });
            long randomDelay = 3000 + (long) (Math.random() * 5 * 1000);
            // 延时等待
            Thread.sleep(randomDelay);
        } catch (Exception e) {

        }
        return 0;
    }

    @Override
    public int sendMessageByCustomerIds(String[] ids, String url) {
        return 0;
    }

    @Override
    public int sendMessageByFansIds(String[] ids, String url) {
        return 0;
    }

    @Override
    public int retrieveRecordsByFansId(String[] ids, String url) {
        return 0;
    }

    @Override
    public int sendBlukByFansId(String[] ids, String url, String message, String messageType) {

        List<FansInfo> list = fansInfoMapper.selectChatByIds(ids);
        list.stream().forEach(fansInfo -> {
            try {
                CustomerInfo customerInfo = customerInfoMapper.selectUserByNumber(fansInfo.getCustomerNumber());
//                int mesType = 0;
//                if (!messageType.equals("text")) {
//                    mesType = 1;
//                }
                WhatsAPPUtils.sendMessage(url, fansInfo.getCustomerNumber(), fansInfo.getClientNumber(), messageType,
                        message, customerInfo.getPersonaId(), false);
            } catch (Exception e) {
                log.error("sendBlukByFansId:" + e);
            }
        });
        return 0;
    }

    @Override
    public int sendBlukByCustomerIds(String[] ids, String url, String message) {
        return 0;
    }

    /**
     * 开启会话
     *
     * @param url
     * @param url
     * @param fansInfo
     */
    public void startDialog(String url, FansInfo fansInfo) {
        SceneDetail sceneDetail = ScenarioDataUtils.startScenario(fansInfo.getClientNumber(), fansInfo.getCustomerNumber());
        if (sceneDetail == null) {
            return;
        }
        sendMessages(sceneDetail, fansInfo);
    }


    private void sendMessages(SceneDetail sceneDetail, FansInfo fansInfo) {
        CompletableFuture.runAsync(() -> {
            try {
                String content = sceneDetail.getContent();
                if (StringUtils.isNotEmpty(fansInfo.getClientName())) {
                    content = content.replace("{fansName}", fansInfo.getClientName());
                }
                String meageData = WhatsAPPUtils.sendMessage(newChatURL, fansInfo.getCustomerNumber(), fansInfo.getClientNumber(), "0", content, "0", true);
                log.info(fansInfo.getCustomerNumber() + " to " + fansInfo.getClientNumber() + " 发送消息：" + sceneDetail.getContent() + " is " + meageData);
                // 获取延时时间（单位：秒）
                String delayTime = "3";
                if (delayTime == null) {
                    delayTime = "5";  // 如果未设置，默认为5秒
                }

                WhatsAPPUtils.randomThread(5, Integer.valueOf(delayTime));
                String keys = "persona:fans:" + fansInfo.getClientNumber() + ":statics";
                redisCache.setCacheObject(keys, "0");

                if (sceneDetail.getImages() != null) {
                    if (sceneDetail.getImages().size() != 0) {
                        for (int i = 0; i < sceneDetail.getImages().size(); i++) {
                            String imageData = WhatsAPPUtils.sendMessage(newChatURL, fansInfo.getCustomerNumber(), fansInfo.getClientNumber(), "1", sceneDetail.getImages().get(i), i + "", false);
                            log.info(fansInfo.getCustomerNumber() + " to " + fansInfo.getClientNumber() + " 发送图片：" + imageData);
                            WhatsAPPUtils.randomThread(3, Integer.valueOf(5));
                        }
                    }
                }
                String currentKey = ScenarioDataUtils.SCENARIO_FANS_KEY_PREFIX + fansInfo.getClientNumber();
                CurrentScenarioData currentScenarioData = redisCache.getCacheObject(currentKey);
                fansInfo.setStepId(currentScenarioData.getCurrentRounds() + "");
                fansInfo.setDaysNumber(currentScenarioData.getCurrentDayNo() + "");
                fansInfo.setScenesId(currentScenarioData.getScenarioName() + "");
                fansInfoMapper.updateDaysNumberByClientNumber(fansInfo);
            } catch (Exception e) {
                log.error("异步执行对话任务失败: " + e.getMessage(), e);
            }
        });
    }

    @Override
    public int combinationMessage(ReceivedMessage receivedMessage) {
        if (!receivedMessage.getMessageType().equals("0")) {
            log.info("receivedMessage MessageType 111:" + receivedMessage.getMessageType());
            return 0;
        }
        log.info("receivedMessage MessageType:" + receivedMessage.getMessageType());
        String fromNumber = receivedMessage.getFromNumber();
        String toNumber = receivedMessage.getToNumber();
        String message = receivedMessage.getMessage();

        // 创建聊天ID (发送者-接收者)
        String chatId = fromNumber + "-" + toNumber;

        String messageKey = WhatsAPPUtils.MESSAGE_KEY_PREFIX + chatId;
        String timestampKey = WhatsAPPUtils.TIMESTAMP_KEY_PREFIX + chatId;
        String countKey = WhatsAPPUtils.COUNT_KEY_PREFIX + chatId;

        // 获取当前消息计数
        Integer messageCount = redisCache.getCacheObject(countKey);
        messageCount = (messageCount == null) ? 0 : messageCount;

        // 保存或更新消息内容
        boolean keyExists = redisCache.hasKey(messageKey);
        if (keyExists) {
            // 如果已存在消息，则追加新消息
            String existingContent = redisCache.getCacheObject(messageKey);
            message = existingContent + " " + message;
        }

        // 保存组合后的消息
        redisCache.setCacheObject(messageKey, message);

        // 更新最后消息时间戳
        long currentTime = System.currentTimeMillis();
        redisCache.setCacheObject(timestampKey, currentTime);

        // 增加消息计数并保存
        messageCount++;
        redisCache.setCacheObject(countKey, messageCount);

        log.info("消息详情 - FromNumber: {}, ToNumber: {}, msgId: {}, MessageType: {}, message: {}",
                fromNumber,
                toNumber,
                receivedMessage.getMsgId(),
                receivedMessage.getMessageType(),
                message);
        return 1;
    }

    /**
     * 处理消息并重置计数
     */
    private void processMessageAndReset(String chatId) {
        try {
            String messageKey = WhatsAPPUtils.MESSAGE_KEY_PREFIX + chatId;
            String timestampKey = WhatsAPPUtils.TIMESTAMP_KEY_PREFIX + chatId;
            String countKey = WhatsAPPUtils.COUNT_KEY_PREFIX + chatId;

            // 获取消息内容
            String combinedMessage = redisCache.getCacheObject(messageKey);

            if (combinedMessage != null) {
                // 解析chatId获取fromNumber和toNumber
                String[] parts = chatId.split("-");
                if (parts.length == 2) {
                    String fromNumber = parts[0];
                    String toNumber = parts[1];

                    String keys = "persona:fans:" + fromNumber + ":statics";
                    String fansStatic = redisCache.getCacheObject(keys);
                    // 检查 fansStatic 是否为 null
                    if ("1".equals(fansStatic)) {
                        // log.info("粉丝："+fromNumber+"暂停回复消息");
                        return;
                    }
                    String isWorkKeys = "persona:customer:" + toNumber + ":work";
                    Integer isWork = redisCache.getCacheObject(isWorkKeys);
                    if (isWork != null && isWork == 1) {
                        log.warn("现在是休息时间，暂停回复:" + fromNumber);
                        return;
                    }
                    // 处理组合后的消息
                    String respose = processMessage(fromNumber, toNumber, combinedMessage);
                    if (respose == null) {
                        return;
                    }
                    // 删除已处理的消息、时间戳和计数
                    redisCache.deleteObject(messageKey);
                    redisCache.deleteObject(timestampKey);
                    redisCache.deleteObject(countKey);

                }
            }
        } catch (Exception e) {
            log.error("processMessageAndReset Exception" + e);
        }
    }


    /**
     * 定时任务，每秒检查一次是否有需要处理的消息
     */
    @Scheduled(fixedRate = 3000)
    public void checkMessagesToProcess() {
        String isOpen = redisCache.getCacheObject("Scheduled:open");
        if ("1".equals(isOpen)) {
            return;
        }
        // 获取所有时间戳键
        Collection<String> timestampKeys = redisCache.keys(WhatsAPPUtils.TIMESTAMP_KEY_PREFIX + "*");

        if (timestampKeys == null || timestampKeys.isEmpty()) {
            return;
        }

        long currentTime = System.currentTimeMillis();
        long processThreshold = WhatsAPPUtils.MESSAGE_COMBINE_SECONDS * 1000;

        for (String timestampKey : timestampKeys) {
            // 获取上次更新时间
            Long lastUpdateTime = redisCache.getCacheObject(timestampKey);

            if (lastUpdateTime == null) {
                continue;
            }

            // 如果超过10秒未更新，则处理该消息
            if (currentTime - lastUpdateTime > processThreshold) {
                String chatId = timestampKey.substring(WhatsAPPUtils.TIMESTAMP_KEY_PREFIX.length());
                processMessageAndReset(chatId);
            }
        }
    }


    /**
     * 处理组合后的数据
     *
     * @param fromNumber
     * @param toNumber
     * @param combinedMessage
     */
    public String processMessage(String fromNumber, String toNumber, String combinedMessage) {
        try {
            // 处理组合后的消息，可以发送给消息处理器或保存到数据库等
            log.info("processMessage 处理组合消息 - FromNumber: {}, ToNumber: {}, 组合消息: {}", fromNumber, toNumber, combinedMessage);

            // TODO: 此处实现具体的消息处理逻辑
            DialogueManagement dialogueManagement = redisCache.getCacheObject(WhatsAPPUtils.getFansDiodlogKey(toNumber, fromNumber));
            if (dialogueManagement == null || !dialogueManagement.isDialogStatus()) {
                return "1";
            }
            if (combinedMessage.length() > 10) {
                if (!redisCache.hasKey("persona:fans:" + fromNumber + ":language")) {
                    String lanuge = WhatsAPPUtils.detectLanguage(combinedMessage);
                    redisCache.setCacheObject("persona:fans:" + fromNumber + ":language", lanuge);
                }
            }
            String respose = "";
            String key = SCENARIO_KEY_PREFIX + toNumber;
            ScenarioData scenario = redisCache.getCacheObject(key);
            String currentKey = SCENARIO_FANS_KEY_PREFIX + fromNumber;
            CurrentScenarioData currentScenarioData = redisCache.getCacheObject(currentKey);
            if (currentScenarioData == null) {
                currentScenarioData = getFault(fromNumber, toNumber);
            }
            SceneDetail sceneDetail = ScenarioDataUtils.turnScene(fromNumber, currentScenarioData, scenario);
            FansInfo fansInfo = fansInfoMapper.selectChatByClientNumber(fromNumber);
            if (sceneDetail != null) {
                //当天所有场景已结束
                if (sceneDetail.isOut()) {
                    return "1";
                }
                sendMessages(sceneDetail, fansInfo);
                respose = "转换场景";
            } else {
                CustomerInfo cus = customerInfoMapper.selectUserByContactNumber(fansInfo.getCustomerNumber());
                String[] prefixes = {"[Cisco]", "[cisCo]", "[cisco]", "[" + cus.getContactName() + "]", "]"};
                String outputKey = "message:content:output";
                String output = redisCache.getCacheObject(outputKey);
                if (StringUtils.isNotEmpty(output)) {
                    combinedMessage = combinedMessage + output;
                }
                combinedMessage = currentScenarioData.getPrompt() + combinedMessage;

                currentScenarioData = redisCache.getCacheObject(currentKey);
                if (currentScenarioData == null) {
                    currentScenarioData = getFault(fromNumber, toNumber);
                }
                if (StringUtils.isNotEmpty(currentScenarioData.getContextLength())) {
                    String logmes = formatPrompt(fromNumber, toNumber, Integer.valueOf(currentScenarioData.getContextLength()));
                    combinedMessage = combinedMessage + "\n你们的历史聊天记录如下：\n" + logmes;
                }

                String resposeBody = WhatsAPPUtils.prefixesBody(combinedMessage, prefixes, fromNumber);
                // 对回复内容进行清理，移除多余的符号和换行符
                respose = WhatsAPPUtils.replaceReponeBody(resposeBody);
                WhatsAPPUtils.sendMessage(newChatURL, toNumber, fromNumber, "0", respose, "1", true);
                currentScenarioData = redisCache.getCacheObject(currentKey);
                if (currentScenarioData != null) {
                    fansInfo.setDaysNumber(currentScenarioData.getCurrentDayNo() + "");
                    fansInfo.setScenesId(currentScenarioData.getScenarioName() + "");
                    fansInfo.setStepId(currentScenarioData.getCurrentRounds() + "");
                    fansInfoMapper.updateDaysNumberByClientNumber(fansInfo);
                }
            }


            return respose;
        } catch (Exception e) {
            log.error("processMessage Exception:" + e);
            return null;
        }

    }

    private CurrentScenarioData getFault(String fromNumber, String toNumber) {
        return new CurrentScenarioData();
    }


    public String formatPrompt(String fansId, String cusNumber, int limit) {
        StringBuilder promptStringBuilder = new StringBuilder();
        CustomerInfo cus = customerInfoMapper.checkContactNumberUnique(cusNumber);

        List<ChatLog> chatlogList = chatLogMapper.selectChatLogByChatType(fansId, limit);
        // 对 chatlogList 进行倒序排序
        for (int i = chatlogList.size() - 1; i >= 0; i--) {
            ChatLog chatLog = chatlogList.get(i);
            if (chatLog.getUserType().equals("0")) {
                if (StringUtils.isNotNull(chatLog.getTranslateText())) {
                    promptStringBuilder.append("[").append(cus.getContactName()).append("]:").append(chatLog.getTranslateText()).append("\n");
                } else {
                    promptStringBuilder.append("[").append(cus.getContactName()).append("]:").append(chatLog.getText()).append("\n");
                }
            } else {
                if (StringUtils.isNotNull(chatLog.getTranslateText())) {
                    promptStringBuilder.append("[user]:").append(chatLog.getTranslateText()).append("\n");
                } else {
                    promptStringBuilder.append("[user]:").append(chatLog.getText()).append("\n");
                }
            }
        }

        return promptStringBuilder.toString();
    }


    /**
     * 更新log翻译，翻译成中文
     */
    @Scheduled(fixedRate = 30 * 1000)
    public void tranChina() {
        String isOpen = redisCache.getCacheObject("Scheduled:open");
        if ("1".equals(isOpen)) {
            return;
        }
        CompletableFuture.runAsync(() -> {
            List<ChatLog> list = chatLogMapper.selectChatByTranslateText();
            if (list == null || list.isEmpty()) {
                return; // 返回空列表，或者返回 null 或其他默认值
            }
            list.stream().forEach(chatLog -> {
                try {
                    if (StringUtils.isNull(chatLog.getTranslateText())) {
                        String text = WhatsAPPUtils.translateByTarget("zh-CN", chatLog.getText());
                        if (StringUtils.isEmpty(text))
                            return;
                        chatLog.setTranslateText(text);
                        chatLogMapper.updateChatLogForTranslateText(chatLog);
                    }
                } catch (Exception e) {
                    log.error("tranChina:" + e);
                }
            });
        });
    }

}
